package com.xyoto.community.service.impl;

import com.xyoto.community.cache.CacheInstruction;
import com.xyoto.community.mapper.comment.DynamicCommentMapper;
import com.xyoto.community.po.DynamicCommentPo;
import com.xyoto.community.service.DynamicCommentReplyTop5ServiceCache;
import com.xyoto.community.utils.RedisCommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author coderFu
 * @create 2021/11/26
 */
@Service
@Slf4j
public class DynamicCommentReplyTop5ServiceCacheImpl implements DynamicCommentReplyTop5ServiceCache {


    @Autowired
    private RedisCommonUtils redisCommonUtils;

    @Autowired
    private DynamicCommentMapper dynamicCommentMapper;

    @Override
    @Async("taskExecutor")
    public void saveCommentReplyCache(Integer commentId, Integer replyId) {
        //判断缓存中是否存在该键值
        Object sourceObject = redisCommonUtils.hget(CacheInstruction.DYNAMIC_COMMENT_REPLY_TOP_5, commentId);
        if (sourceObject == null){
            //在此再次检测，防止因并发问题出现重复创建
            Object doubleCheck = redisCommonUtils.hget(CacheInstruction.DYNAMIC_COMMENT_REPLY_TOP_5, commentId);
            if (doubleCheck != null){
                //缓存中已有对象，取出集合
                List replyIds = (List)redisCommonUtils.hget(CacheInstruction.DYNAMIC_COMMENT_REPLY_TOP_5, commentId);
                if (replyIds.size() <CacheInstruction.MAX_CACHE_COMMENT_REPLY_COUNT){
                    replyIds.add(replyId);
                }
                //缓存中没有对象，创建存储回复id的集合
                List<Integer> replyIdContains = new ArrayList<>();
                replyIdContains.add(replyId);
                //存储到redis中
                redisCommonUtils.hset(CacheInstruction.DYNAMIC_COMMENT_REPLY_TOP_5,String.valueOf(commentId),replyIdContains,CacheInstruction.COMMENT_REPLY_EXPIRE_TIME);
            }
        }
    }

    @Override
    @Async("taskExecutor")
    public void deleteCommentReplyCache(Integer commentId, Integer replyId) {
        if (replyId == null) {
            //根据评论id删除缓存
            redisCommonUtils.hdel(CacheInstruction.DYNAMIC_COMMENT_REPLY_TOP_5, String.valueOf(commentId));
        } else {
            Object sourceObj = redisCommonUtils.hget(CacheInstruction.DYNAMIC_COMMENT_REPLY_TOP_5, commentId);
            if (sourceObj != null) {
                List<Integer> replyIds = (List) sourceObj;
                replyIds.remove(replyId);
                redisCommonUtils.hset(CacheInstruction.DYNAMIC_COMMENT_REPLY_TOP_5,String.valueOf(commentId),replyIds);
            }
        }
    }

    @Override
    public List<Integer> getTop5ReplyIdByCommentIdFromCache(Integer commentId) {
        //从缓存中取出评论回复信息
        if (commentId == null){
            return new ArrayList<>();
        }
        Object sourceObj = redisCommonUtils.hget(CacheInstruction.DYNAMIC_COMMENT_REPLY_TOP_5, commentId);
        if (sourceObj == null){
            //缓存已过期，更新缓存中的信息
            Object sourceObj2 = redisCommonUtils.hget(CacheInstruction.DYNAMIC_COMMENT_REPLY_TOP_5, commentId);
            if (sourceObj2 != null){
                return (List<Integer>)sourceObj2;
            }
            return updateTop5ReplyCache(commentId);
        }
            return (List<Integer>) sourceObj;
    }

    /**
     * 更新缓存数据
     * @param commentId
     * @return
     */
    public  synchronized List<Integer>  updateTop5ReplyCache(Integer commentId){
        //再次从缓存中获取
        //doubleCheck 双重检查
        Object sourceObj2 = redisCommonUtils.hget(CacheInstruction.DYNAMIC_COMMENT_REPLY_TOP_5, commentId);
        if (sourceObj2 != null){
            return (List<Integer>)sourceObj2;
        }
        //查询数据库
        DynamicCommentPo dynamicCommentPo = dynamicCommentMapper.getDynamicCommentMessageByCommentId(commentId);
        List<Integer> replyIds = new ArrayList<>();
        replyIds.add(dynamicCommentPo.getReplyFirstId());
        replyIds.add(dynamicCommentPo.getReplySecondId());
        //存储到缓存
        redisCommonUtils.hset(CacheInstruction.DYNAMIC_COMMENT_REPLY_TOP_5,String.valueOf(commentId),replyIds,CacheInstruction.COMMENT_REPLY_EXPIRE_TIME);
        return replyIds;
    }
}
